package com.awx.server.dao.hibernate;

import org.apache.log4j.Logger;
import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;

public class HibernateSessionFactory {
	
	private static String CONFIG_FILE_LOCATION = "/hibernatecfg/hibernate.cfg.xml";
	private static final ThreadLocal<Session> threadLocalSession = new ThreadLocal<Session>();
	private static final ThreadLocal<Transaction> threadLocalTransaction = new ThreadLocal<Transaction>();
    private static Configuration configuration = new Configuration();
    private static SessionFactory sessionFactory;
    private static String configFile = CONFIG_FILE_LOCATION;
    
    /*Investigar bien esto de Log4j*/
    private Logger log = Logger.getLogger(HibernateSessionFactory.class);
  
    private HibernateSessionFactory() {
    }
    
    public static Session getSession() throws HibernateException{
    	Session session = threadLocalSession.get();
    	
    	if(session != null && !session.isOpen()) session = null;
    	if(session == null){
    		if(sessionFactory == null){
    			rebuildSessionFactory();
    		}
    		session = (sessionFactory != null) ? sessionFactory.openSession():null;
    		threadLocalSession.set(session);
    	}
    	
    	return session;
    }
    
    public static void rebuildSessionFactory(){
    	try{
    		configuration.configure(CONFIG_FILE_LOCATION);
    		sessionFactory = configuration.buildSessionFactory();
    	} catch (Throwable ex) {
			System.err.println("-- Error al Construir SessionFactory");
			throw new ExceptionInInitializerError("Initial SessionFactory creation failed." + ex);
		}
    }
    
    public static void closeSession(){
    	Session session = threadLocalSession.get();
    	threadLocalSession.set(null);
    	
    	if(session != null && session.isOpen()){
    		session.close();
    	}
    }
    
    public static SessionFactory getSessionFactory(){
    	return sessionFactory;
    }
    
    public static void setConfigFile(String configFile){
    	HibernateSessionFactory.configFile = configFile;
    	sessionFactory = null;
    }
    
    public static Configuration getConfiguration(){
    	return configuration;
    }
    
    public static void beginTransaction(){
    	Transaction tx = threadLocalTransaction.get();
    	
    	if(tx == null){
    		tx = getSession().beginTransaction();
    		threadLocalTransaction.set(tx);
    	}
    }
    
    public static void commitTransaction(){
    	Transaction tx = threadLocalTransaction.get();
    	
    	if(tx != null && !tx.wasCommitted() && !tx.wasRolledBack()){
    		tx.commit();
    	}
    	threadLocalTransaction.set(null);
    }
    
    public static void rollbackTransaction(){
    	try{
    		Transaction tx = threadLocalTransaction.get();
    		
    		if(tx != null && !tx.wasRolledBack() && !tx.wasCommitted()){
    			tx.rollback();
    		}
    		threadLocalSession.set(null);
    	} finally {
    		closeSession();
    	}
    }
    
}
